package com.xmtlxx.web.controller.wms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xmtlxx.common.core.domain.PageQuery;
import com.xmtlxx.common.core.domain.entity.SysDept;
import com.xmtlxx.common.core.page.TableDataInfo;
import com.xmtlxx.common.enums.PropertyLogNode;
import com.xmtlxx.common.enums.PropertyLogType;
import com.xmtlxx.common.exception.ServiceException;
import com.xmtlxx.common.helper.LoginHelper;
import com.xmtlxx.common.tengbo.PushDatasUtil;
import com.xmtlxx.common.tengbo.vo.PropertyLogModelsVo;
import com.xmtlxx.common.tengbo.vo.SmartCabinetInVo;
import com.xmtlxx.common.utils.DateUtils;
import com.xmtlxx.common.utils.JsonUtils;
import com.xmtlxx.common.utils.StringUtils;
import com.xmtlxx.oms.domain.*;
import com.xmtlxx.oms.domain.vo.StagingVo;
import com.xmtlxx.oms.domain.vo.TaskVo;
import com.xmtlxx.oms.mapper.*;
import com.xmtlxx.system.domain.SysOss;
import com.xmtlxx.system.domain.bo.SysOssBo;
import com.xmtlxx.system.mapper.SysDeptMapper;
import com.xmtlxx.system.mapper.SysOssMapper;
import com.xmtlxx.tms.domain.Order;
import com.xmtlxx.tms.domain.vo.OrderVo;
import com.xmtlxx.tms.mapper.OrderMapper;
import com.xmtlxx.web.controller.center.service.ICommonService;
import com.xmtlxx.web.controller.oms.service.IStagingService;
import com.xmtlxx.web.controller.wms.service.IPutTaskService;
import com.xmtlxx.wms.domain.*;
import com.xmtlxx.wms.domain.bo.*;
import com.xmtlxx.wms.domain.vo.*;
import com.xmtlxx.wms.mapper.*;
import com.xmtlxx.wms.service.IInventoryService;
import com.xmtlxx.wms.service.IStoreLogService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 上架任务Service业务层处理
 *
 * @author xmtlxx
 * @date 2022-08-15
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class PutTaskServiceImpl implements IPutTaskService {

    private final PutTaskMapper baseMapper;

    private final PutDtlMapper putDtlMapper;

    private final SysOssMapper sysOssMapper;

    private final WarehouseMapper warehouseMapper;

    private final WarehouseDtlMapper warehouseDtlMapper;

    private final IStoreLogService iStoreLogService;

    private final IInventoryService iInventoryService;

    private final OperatorLogMapper logMapper;

    private final PropertyLogMapper propertyLogMapper;

    private final BoxMapper boxMapper;

    private final StoreAreaMapper storeAreaMapper;

    private final LocatorMapper locatorMapper;

    private final TaskMapper taskMapper;

    private final OrderMapper orderMapper;


    private final StoreMapper storeMapper;

    private final PropertyMapper propertyMapper;

    private final CabinetGroupMapper cabinetGroupMapper;

    private final SysOssMapper ossMapper;

    private final SysDeptMapper deptMapper;

    private final ICommonService commonService;

    private final IStagingService stagingService;

    /**
     * 查询上架任务
     *
     * @param id 上架任务主键
     * @return 上架任务
     */
    @Override
    public PutTaskVo queryById(String id) {
        //return baseMapper.selectVoById(id);
        return baseMapper.selectPutTaskVoByID(id);
    }

    @Override
    public PutTaskVo queryByTaskId(String id) {

        PutTaskVo vo = null;
        PutTaskBo bo = new PutTaskBo();
        bo.setTaskId(id);
        List<PutTaskVo> vos = baseMapper.selectPutTaskList(bo);
        if (vos != null && vos.size() > 0) {
            vo = vos.get(0);
        }
        return vo;
    }

    /**
     * 查询上架任务列表
     *
     * @param bo 上架任务
     * @return 上架任务
     */
    @Override
    public TableDataInfo<PutTaskVo> queryPageList(PutTaskBo bo, PageQuery pageQuery) {
        // LambdaQueryWrapper<PutTask> lqw = buildQueryWrapper(bo);
        // Page<PutTaskVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        Page<PutTaskVo> result = baseMapper.selectPagePutTaskList(pageQuery.build(), bo);
        return TableDataInfo.build(result);
    }

    @Override
    public List<SysOss> getPics(String dtlId) {

        PutDtl dtl = putDtlMapper.selectById(dtlId);
        PutTask putTask = baseMapper.selectById(dtl.getTaskId());
        StagingVo stagingVo = stagingService.getVoByNo(dtl.getPno());
        WarehouseVo warehouseVo = warehouseMapper.selectWarehouseVoByID(putTask.getWid());
        OrderVo orderVo = null;
        if (warehouseVo != null) {
            orderVo = orderMapper.selectVoOne(new LambdaQueryWrapper<Order>().eq(Order::getTaskId, warehouseVo.getTaskId()));
        }

        List<SysOss> soss = new ArrayList<>();
        SysOssBo orderOssBo = new SysOssBo();

        if (stagingVo != null) {
            SysOssBo sossBo = new SysOssBo();
            sossBo.setObjid(stagingVo.getId());
            sossBo.setBuss("staging");

            soss.addAll(ossMapper.selectSysOssList(sossBo));
        }

        if (ObjectUtil.isNotNull(orderVo)) {

            orderOssBo.setObjid(orderVo.getId());
            orderOssBo.setBuss("facade");
            List<SysOss> facadeOss = ossMapper.selectSysOssList(orderOssBo);
            soss.addAll(facadeOss);

            orderOssBo.setObjid(orderVo.getId());
            orderOssBo.setBuss("flaw");
            List<SysOss> flawOss = ossMapper.selectSysOssList(orderOssBo);
            soss.addAll(flawOss);

            orderOssBo.setObjid(orderVo.getId());
            orderOssBo.setBuss("carNumber");
            List<SysOss> carOss = ossMapper.selectSysOssList(orderOssBo);
            soss.addAll(carOss);

            orderOssBo.setBuss("handover");
            List<SysOss> handoverOss = ossMapper.selectSysOssList(orderOssBo);
            soss.addAll(handoverOss);

            orderOssBo.setBuss("load");
            List<SysOss> loadOss = ossMapper.selectSysOssList(orderOssBo);
            soss.addAll(loadOss);

            orderOssBo.setBuss("take");
            List<SysOss> takeOss = ossMapper.selectSysOssList(orderOssBo);
            soss.addAll(takeOss);

            orderOssBo.setBuss("unload");
            List<SysOss> unloadOss = ossMapper.selectSysOssList(orderOssBo);
            soss.addAll(unloadOss);

            orderOssBo.setObjid(orderVo.getId());
            orderOssBo.setBuss("other");
            List<SysOss> otherOss = ossMapper.selectSysOssList(orderOssBo);
            soss.addAll(otherOss);

            orderOssBo.setObjid(orderVo.getId());
            orderOssBo.setBuss("otherTwo");
            List<SysOss> otherTwoOss = ossMapper.selectSysOssList(orderOssBo);
            soss.addAll(otherTwoOss);
        }
        return soss;
    }

    /**
     * 查询上架任务列表
     *
     * @param bo 上架任务
     * @return 上架任务
     */
    @Override
    public List<PutTaskVo> queryList(PutTaskBo bo) {
        // LambdaQueryWrapper<PutTask> lqw = buildQueryWrapper(bo);
        // return baseMapper.selectVoList(lqw);
        return baseMapper.selectPutTaskList(bo);
    }

    private LambdaQueryWrapper<PutTask> buildQueryWrapper(PutTaskBo bo) {

        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<PutTask> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getWid()), PutTask::getWid, bo.getWid());
        lqw.eq(bo.getDeptId() != null, PutTask::getDeptId, bo.getDeptId());
        lqw.eq(StringUtils.isNotBlank(bo.getTaskNo()), PutTask::getTaskNo, bo.getTaskNo());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), PutTask::getStatus, bo.getStatus());
        lqw.eq(bo.getOperator() != null, PutTask::getOperator, bo.getOperator());
        lqw.between(params.get("beginFinishTime") != null && params.get("endFinishTime") != null,
                PutTask::getFinishTime, params.get("beginFinishTime"), params.get("endFinishTime"));
        lqw.eq(StringUtils.isNotBlank(bo.getCreateBy()), PutTask::getCreateBy, bo.getCreateBy());
        lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
                PutTask::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime"));
        lqw.eq(StringUtils.isNotBlank(bo.getUpdateBy()), PutTask::getUpdateBy, bo.getUpdateBy());
        lqw.between(params.get("beginUpdateTime") != null && params.get("endUpdateTime") != null,
                PutTask::getUpdateTime, params.get("beginUpdateTime"), params.get("endUpdateTime"));
        lqw.eq(StringUtils.isNotBlank(bo.getDelFlag()), PutTask::getDelFlag, bo.getDelFlag());
        return lqw;
    }

    /**
     * 新增上架任务
     *
     * @param bo 上架任务
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public PutTask insertByBo(PutTaskBo bo) {

        PutTask add = BeanUtil.toBean(bo, PutTask.class);
        validEntityBeforeSave(add);

        //填充UUID
        add.setId(IdUtil.simpleUUID());
        add.setDelFlag("0");
        add.setStatus("0");

        if (bo.getItems() != null && bo.getItems().size() > 0) {
            List<PutDtl> dtls = bo.getItems().stream().map(item -> {
                PutDtl dtl = new PutDtl();
                BeanUtil.copyProperties(item, dtl, "id");
                dtl.setId(IdUtil.simpleUUID());
                dtl.setTaskId(add.getId());
                dtl.setDelFlag("0");
                dtl.setStatus("0");
                dtl.setPrintFlag(0);

                /**
                 * 日志
                 */
                String logContent = "创建上架任务：(物品编号：" + item.getPno() + "，物品名称：" + item.getName() + "，上架说明：" + (StringUtils.isNotEmpty(add.getMemo()) ? add.getMemo() : "") + ")";
                String info = JsonUtils.toJsonString(dtl);
                commonService.savePropertyLog(item.getPno(), add.getId(), item.getName(), PropertyLogType.PUT_TASK.getCode(), logContent, add.getDeptId(), info, dtl.getStoreId(), add.getNums(), null);

                return dtl;
            }).collect(Collectors.toList());

            if (!putDtlMapper.insertBatch(dtls)) {
                throw new ServiceException("更新上架财物信息失败");
            }
        }

        if (bo.getOss() != null && bo.getOss().size() > 0) {
            for (SysOss oss : bo.getOss()) {
                oss.setBuss("PutDtl");
                oss.setObjid(add.getId());
                if (sysOssMapper.updateById(oss) == 0) {
                    throw new ServiceException("更新上架附件失败");
                }
            }
        }

        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        } else {
            throw new ServiceException("更新上架任务失败");
        }

        WarehouseVo warehouseVo = warehouseMapper.selectWarehouseVoByID(add.getWid());

        commonService.saveOperatorLog(StringUtils.isNotEmpty(warehouseVo.getTaskId()) ? warehouseVo.getTaskId() : warehouseVo.getId(), "wms", "上架");

        return add;
    }

    /**
     * 修改上架任务
     *
     * @param bo 上架任务
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public PutTaskVo updateByBo(PutTaskBo bo) {

        PutTask update = BeanUtil.toBean(bo, PutTask.class);
        WarehouseVo warehouseVo = warehouseMapper.selectWarehouseVoByID(update.getWid());
        TaskVo taskVo = taskMapper.selectVoById(warehouseVo.getTaskId());
        validEntityBeforeSave(update);
        List<PutDtl> dtls = new ArrayList<>();
        Long nums = 0L;

        //获取已满库位id
        List<String> locatorIds = new ArrayList<>();
        List<SysOss> ossList = new ArrayList<>();

        if (bo.getItems() != null && bo.getItems().size() > 0) {

            List<Box> boxes = new ArrayList<>();
            List<String> locatorstr = new ArrayList<>();
            bo.getItems().stream().forEach(item -> {
                if (StringUtils.isNotEmpty(item.getLocatorStatus()) && item.getLocatorStatus().equals("1")) {
                    if (!locatorIds.contains(item.getLocatorId())) {
                        locatorIds.add(item.getLocatorId());
                    }
                }
            });

            dtls = bo.getItems().stream().map(item -> {
                PutDtl dtl = putDtlMapper.selectById(item.getId());
                if (dtl == null) {
                    dtl = new PutDtl();
                    BeanUtil.copyProperties(item, dtl, "id");
                    dtl.setId(IdUtil.simpleUUID());
                    dtl.setTaskId(update.getId());
                    dtl.setDelFlag("0");
                    dtl.setStatus("0");
                    dtl.setPrintFlag(0);
                } else {
                    BeanUtil.copyProperties(item, dtl);

                    //处理箱号
//                    Box box = null;
//                    if(StringUtils.isNotEmpty(dtl.getBoxNo())){
//                        box= boxMapper.selectOne(new LambdaQueryWrapper<Box>().eq(Box::getBoxNo,dtl.getBoxNo()));
//                        if(box == null){
//                            box = new Box();
//                            box.setId(IdUtil.simpleUUID());
//                            box.setBoxNo(dtl.getBoxNo());
//                            box.setDeptId(LoginHelper.getDeptId());
//                            box.setCreateDept(LoginHelper.getDeptId());
//                            box.setDelFlag("0");
//                            box.setStatus("1");
//                            boxMapper.insert(box);
//                        }
//                        //箱子所在部门与申请账号部门不一致时，变更箱子所在部门为当前账号部门
//                        if(box.getDeptId() != null && (box.getDeptId() != LoginHelper.getDeptId())){
//                            box.setDeptId(LoginHelper.getDeptId());
//                        }
//                        if(box.getStatus().equals("0")){
//                            //设置为已使用
//                            box.setStatus("1");
//                        }
//                        boxMapper.insertOrUpdate(box);
//                    }

//                    if(box != null){
//                        dtl.setBoxId(box.getId());
//                        if(!boxes.contains(box)){
//                            boxes.add(box);
//                        }
//                    }
                }

                //处理格口信息
                if (StringUtils.isNotEmpty(item.getLocatorId()) && !locatorstr.contains(item.getLocatorId())) {
                    locatorstr.add(item.getLocatorId());
                }

                //交接清单附件
                if (item.getOss() != null && item.getOss().size() > 0) {
                    for (SysOss oss : item.getOss()) {
                        if (StringUtils.isNotEmpty(dtl.getBoxId())) {
                            SysOss copyOss = new SysOss();
                            BeanUtil.copyProperties(oss, copyOss, "ossId");
                            copyOss.setObjid(dtl.getId());
                            copyOss.setBuss("putDtl");
                            if (!ossMapper.insertOrUpdate(copyOss)) {
                                throw new ServiceException("更新保存交接清单附件失败");
                            }
                            ossList.add(copyOss);
                        } else {
                            oss.setObjid(dtl.getId());
                            oss.setBuss("putDtl");
                            if (!ossMapper.insertOrUpdate(oss)) {
                                throw new ServiceException("更新保存交接清单附件失败");
                            }
                            ossList.add(oss);
                        }
                    }
                }

                //处理财物入库编号
                Property property = propertyMapper.selectOne(new LambdaQueryWrapper<Property>().eq(Property::getPno, dtl.getPno()));

                if (property != null && StringUtils.isNotEmpty(dtl.getQrcode())) {
                    property.setQrcode(dtl.getQrcode());
                    property.setCarType(item.getCarType());

                    if (propertyMapper.updateById(property) ==0) {
                        throw new ServiceException("更新财物表信息失败");
                    }
                }

                return dtl;
            }).collect(Collectors.toList());

            //处理格口信息
            if (locatorstr.size() > 0) {
                List<Locator> locatorList = locatorstr.stream().map(locatorId -> {
                    Locator locator = locatorMapper.selectById(locatorId);
                    if (locator.getStatus().equals("0")) {
                        locator.setStatus("1");//设为已使用
                    }
                    return locator;
                }).collect(Collectors.toList());

                if (!locatorMapper.updateBatchById(locatorList)) {
                    throw new ServiceException("处理格口信息失败");
                }
            }

            //计算财物数量
            nums = dtls.stream().mapToLong(PutDtl::getNums).sum();

            //箱子使用记录
//            if(boxes != null && boxes.size() > 0){
//                for (Box box:boxes){
//                    BoxDept boxDept = new BoxDept();
//                    boxDept.setId(IdUtil.simpleUUID());
//                    boxDept.setBoxId(box.getId());
//                    boxDept.setBoxNo(box.getBoxNo());
//                    boxDept.setBoxDept(box.getDeptId());
//                    boxDept.setStatus("1");
//                    boxDept.setDelFlag("0");
//                    boxDeptMapper.insert(boxDept);
//                }
//            }

        }
        //更新库位状态
        List<Locator> locatorList = locatorIds.stream().map(id -> {
            Locator locator = new Locator();
            locator.setId(id);
            locator.setStatus("2");
            return locator;
        }).collect(Collectors.toList());

        if(CollectionUtil.isNotEmpty(locatorList)){
            if (!locatorMapper.insertOrUpdateBatch(locatorList)) {
                throw new ServiceException("更新库位状态失败");
            }
        }

        update.setNums(nums);

        if (dtls.size() > 0) {
            if (!putDtlMapper.insertOrUpdateBatch(dtls)) {
                throw new ServiceException("更新上架财物失败");
            }
        }

        if (baseMapper.updateById(update) ==0) {
            throw new ServiceException("更新上架信息失败");
        }
        if (update.getStatus().equals("1")) {//完成上架 生成库存记录及入库日志
            Warehouse warehouse = warehouseMapper.selectById(update.getWid());
            if (warehouse == null || StringUtils.isEmpty(warehouse.getIsSign()) || !warehouse.getIsSign().equals("1")) {
                throw new ServiceException("入库单未签收，请签收后上架！");
            }
            for (PutDtl dtl : dtls) {
                if (dtl.getStatus().equals("0")) {//限制已单独上架的物品不再重复上架

                    //生成库存
                    InventoryBo inBo = new InventoryBo();
                    inBo.setStoreId(dtl.getStoreId());
                    inBo.setAreaId(dtl.getAreaId());
                    inBo.setLocatorId(dtl.getLocatorId());
                    inBo.setPno(dtl.getPno());
                    inBo.setName(dtl.getName());
                    inBo.setInnums(dtl.getNums());
                    inBo.setNums(dtl.getNums());
                    inBo.setUnit(dtl.getUnit());
                    inBo.setPutTaskType("0");
                    if (StringUtils.isNotEmpty(taskVo.getReturnId())) {//归还入库单上架
                        inBo.setPutTaskType("1");
                    }

                    /**
                     * 获取物品的扣押单位
                     */
                    Property property = propertyMapper.selectOne(new LambdaQueryWrapper<Property>().eq(Property::getPno, dtl.getPno()));


                    inBo.setDeptId(property.getOfficeId());
                    inBo.setPics(dtl.getPics());
                    inBo.setDelFlag("0");
                    inBo.setTaskId(update.getId());
                    inBo.setMark("0");
                    inBo.setQrcode(dtl.getQrcode());
                    inBo.setBoxNo(dtl.getBoxNo());
                    inBo.setPassword(dtl.getPassword());
                    inBo.setPutPassword(dtl.getPutPassword());

                    if (!iInventoryService.addInventory(inBo)) {
                        throw new ServiceException("加库存失败");
                    }

                    //生成仓库日志  0-入库；1-出库 2-处置 3-上架 4-挑拣 5-看样
                    StoreLogBo logBo = new StoreLogBo();
                    logBo.setDeptId(update.getDeptId());
                    logBo.setStoreId(dtl.getStoreId());
                    logBo.setLogTime(new Date());
                    logBo.setUserId(LoginHelper.getUserId());
                    logBo.setOperator(LoginHelper.getUsername());
                    logBo.setLogType("3");
                    logBo.setDelFlag("0");
                    logBo.setContent(JsonUtils.toJsonString(bo));
                    if (!iStoreLogService.insertByBo(logBo)) {
                        throw new ServiceException("生成仓库日志失败");
                    }

                    //生成财物日志维护财物状态
//                   Property property = propertyMapper.selectOne(new LambdaQueryWrapper<Property>().eq(Property::getPno,dtl.getPno()));
                    property.setBelongDeptId(update.getDeptId());
                    property.setBelongStoreId(dtl.getStoreId());
                    property.setLocatorId(dtl.getLocatorId());
                    if (propertyMapper.updateById(property)==0) {
                        throw new ServiceException("更新财物表信息失败");
                    }


                    String logContent = "完成上架任务：(物品编号：" + dtl.getPno() + "，物品名称：" + dtl.getName() + "，上架说明：" + (StringUtils.isNotEmpty(update.getMemo()) ? update.getMemo() : "") + ")";
                    String info = JsonUtils.toJsonString(dtl);
                    commonService.savePropertyLog(dtl.getPno(), update.getId(), dtl.getName(), PropertyLogType.PUT_TASK.getCode(), logContent, update.getDeptId(), info, dtl.getStoreId(), update.getNums(), ossList);

                    //完成上架
                    dtl.setStatus("1");

                    if (!putDtlMapper.insertOrUpdate(dtl)) {
                        throw new ServiceException("更新上架财物失败");
                    }
                }
            }
            /**
             * 更新完成时间
             */
            if (update.getOperator() == null) {
                update.setOperator(LoginHelper.getUserId());
            }
            update.setFinishTime(new Date());

            if (baseMapper.updateById(update) ==0) {
                throw new ServiceException("更新上架信息失败");
            }

            //更新入库单上架状态
//            Warehouse warehouse = warehouseMapper.selectById(update.getWid());
            if (warehouse != null) {
                warehouse.setIsFinish("1");//完成上架
                if (warehouseMapper.updateById(warehouse)==0) {
                    throw new ServiceException("更新入库单上架状态失败");
                }
            }

            commonService.saveOperatorLog(StringUtils.isNotEmpty(warehouseVo.getTaskId()) ? warehouseVo.getTaskId() : warehouseVo.getId(), "wms", "完成上架");
            //判断当前是否已完成下发任务
//            TaskVo taskVo = taskMapper.selectTaskVoByID(warehouseVo.getTaskId());
            if (taskVo != null) {
                if (taskVo.getDelivery().equals("0")) {
                    OrderVo orderVo = orderMapper.selectVoOne(new LambdaQueryWrapper<Order>().eq(Order::getTaskId, taskVo.getId()));
                    if (orderVo != null && orderVo.getStatus().equals("3")) {
                        taskVo.setStatus("1");
                    }
                } else {
                    if (warehouseVo.getIsSign().equals("1")) {
                        taskVo.setStatus("1");
                    }
                }
                Task task = new Task();
                BeanUtil.copyProperties(taskVo, task);
                if (taskMapper.updateById(task)==0) {
                    throw new ServiceException("更新任务状态失败");
                }
            }

        }

        PutTaskVo vo = new PutTaskVo();
        BeanUtil.copyProperties(update, vo);
        return vo;
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(PutTask entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除上架任务
     *
     * @param ids 需要删除的上架任务主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {

        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public PutTaskVo queryPutTaskVoByWarehouseID(String warehouseID) {

        WarehouseVo warehouseVo = warehouseMapper.selectWarehouseVoByID(warehouseID);
        PutTaskVo vo = baseMapper.queryPutTaskVoByWarehouseID(warehouseID);
        if (vo != null) {
            PutDtlBo bo = new PutDtlBo();
            bo.setTaskId(vo.getId());
            bo.setDelFlag("0");
            /**
             * 变更仓库，上架明细同步更新
             */
            List<PutDtlVo> putDtlVos = putDtlMapper.selectPutDtlList(bo);
            PutTaskVo finalVo = vo;
            List<PutDtl> dtls = putDtlVos.stream().map(item -> {
                PutDtl dtl = BeanUtil.toBean(item, PutDtl.class);
                dtl.setStoreId(finalVo.getStoreId());
                return dtl;
            }).collect(Collectors.toList());
            boolean flag = putDtlMapper.updateBatchById(dtls);
            if (flag) {
                vo.setItems(putDtlMapper.selectPutDtlList(bo));
            }

        } else {
            PutTask add = new PutTask();
            add.setId(IdUtil.simpleUUID());
            add.setDelFlag("0");
            add.setWid(warehouseID);
            add.setDeptId(warehouseVo.getDeptId());
            add.setTaskNo(warehouseVo.getWno());
            add.setStatus("0");
            List<PutDtl> dtls = new ArrayList<>();
            Long nums = 0l;

            WarehouseDtlBo dtlBo = new WarehouseDtlBo();
            dtlBo.setWid(warehouseID);
            List<WarehouseDtlVo> warehouseDtlVos = warehouseDtlMapper.selectWarehouseDtlList(dtlBo);
            List<PutDtlVo> dtlVos = new ArrayList<>();
            if (warehouseDtlVos != null && warehouseDtlVos.size() > 0) {
                for (WarehouseDtlVo item : warehouseDtlVos) {
                    PutDtl dtl = new PutDtl();
                    dtl.setId(IdUtil.simpleUUID());
                    dtl.setTaskId(add.getId());
                    dtl.setDelFlag("0");
                    dtl.setPno(item.getPno());
                    dtl.setName(item.getName());
                    dtl.setStoreId(warehouseVo.getStoreId());

                    InventoryVo inventory = iInventoryService.queryByPno(item.getPno(), warehouseVo.getStoreId(), null);
                    if (inventory != null) {
                        dtl.setAreaId(inventory.getAreaId());
                        dtl.setLocatorId(inventory.getLocatorId());
                    }

                    dtl.setStatus("0");
                    dtl.setNums(item.getNums() == null ? 1L : item.getNums());
                    dtl.setUnit(item.getUnit());
                    dtl.setPrintFlag(0);
                    dtls.add(dtl);
                    nums += dtl.getNums();

                    String content = "新增上架：(物品编号：" + dtl.getPno() + "，物品名称：" + dtl.getName() + "，上架说明：" + (StringUtils.isNotEmpty(add.getMemo()) ? add.getMemo() : "") + ")";
                    PropertyLog propertyLog = saveLog(dtl, add.getId(), add.getDeptId(), dtl.getStoreId(), "新增上架", add.getDeptId(), null);
//                    propertyLogMapper.insert(propertyLog);
                    PropertyLogModelsVo pushData = new PropertyLogModelsVo();
                    pushData.setApi("proBase");
                    pushData.setData(propertyLogMapper.selectPropertyLogVoByID(propertyLog.getId()));
                    PushDatasUtil.pushPropertyDatas(pushData);
                }
            }
            if (dtls != null && dtls.size() > 0) {
                putDtlMapper.insertBatch(dtls);
            }
            add.setNums(nums);
            baseMapper.insert(add);

            vo = baseMapper.queryPutTaskVoByWarehouseID(warehouseID);
            PutDtlBo bo = new PutDtlBo();
            bo.setTaskId(vo.getId());
            bo.setDelFlag("0");
            vo.setItems(putDtlMapper.selectPutDtlList(bo));

            addOperatorLog(StringUtils.isNotEmpty(warehouseVo.getTaskId()) ? warehouseVo.getTaskId() : warehouseVo.getId(), "wms", "上架");
        }
        vo.setBuss(warehouseVo.getBuss());
        return vo;
    }

    @Override
    public PutTaskVo putTaskVoByWarehouse(String warehouseId) {

        PutTaskVo vo = null;
        PutTask add = new PutTask();
        if (StringUtils.isNotEmpty(warehouseId)) {
            vo = baseMapper.queryPutTaskVoByWarehouseID(warehouseId);
            WarehouseVo warehouseVo = warehouseMapper.selectWarehouseVoByID(warehouseId);
            List<PutDtlVo> dtls = null;
            WarehouseDtlBo bo = new WarehouseDtlBo();
            bo.setWid(warehouseId);
            List<WarehouseDtlVo> warehouseDtls = warehouseDtlMapper.selectWarehouseDtlList(bo);
            TaskVo taskVo = taskMapper.selectVoById(warehouseVo.getTaskId());
            //创建新的上架信息
            if (vo == null) {
                vo = new PutTaskVo();
                vo.setDeptId(storeMapper.selectVoById(warehouseVo.getStoreId()).getDeptId());//仓库所属部门设置
                vo.setTaskNo(warehouseVo.getWno());
                vo.setWid(warehouseId);

                dtls = warehouseDtls.stream().map(item -> {
                    PutDtlVo dtl = new PutDtlVo();
                    BeanUtil.copyProperties(item, dtl, "id");
                    dtl.setOperator(LoginHelper.getUserId());
                    dtl.setStoreId(warehouseVo.getStoreId());
                    if (StringUtils.isNotEmpty(item.getPassword())) {
                        dtl.setPassword(item.getPassword());
                    }
                    dtl.setIsPwd(false);
                    dtl.setOss(new ArrayList<>());
                    dtl.setPrintFlag(0);
                    return dtl;
                }).collect(Collectors.toList());

                //设置上架总数
                vo.setNums(warehouseVo.getNums());
                vo.setStoreId(warehouseVo.getStoreId());
                vo.setStatus("0");

                /**
                 * 新增上架任务
                 */
                BeanUtil.copyProperties(vo, add);
                add.setId(IdUtil.simpleUUID());
                boolean flag = baseMapper.insert(add) > 0;
                if (flag) {
                    vo.setId(add.getId());
                }

                List<PutDtl> putDtls = dtls.stream().map(item -> {
                    PutDtl putDtl = new PutDtl();
                    BeanUtil.copyProperties(item, putDtl, "id");
                    putDtl.setId(IdUtil.simpleUUID());
                    putDtl.setTaskId(add.getId());
                    putDtl.setStatus("0");
                    return putDtl;
                }).collect(Collectors.toList());

                putDtlMapper.insertBatch(putDtls);

                dtls = putDtls.stream().map(item -> {
                    PutDtlVo putDtlVo = new PutDtlVo();
                    BeanUtil.copyProperties(item, putDtlVo);
                    return putDtlVo;
                }).collect(Collectors.toList());

            } else {
                PutDtlBo putDtlBo = new PutDtlBo();
                putDtlBo.setTaskId(vo.getId());
                putDtlBo.setDelFlag("0");
                dtls = putDtlMapper.selectPutDtlList(putDtlBo);
            }
            vo.setItems(dtls);
        }

        return vo;
    }

    @Override
    public List<PutDtlVo> deleteWithBoxByIds(String boxId, String id) {

        List<PutDtl> putDtls = putDtlMapper.selectList(new LambdaQueryWrapper<PutDtl>().eq(PutDtl::getTaskId, id));
        //移除上架明细中的箱子
        if (putDtls != null && putDtls.size() > 0) {
            putDtls.stream().forEach(item -> {
                if (item.getBoxId().equals(boxId)) {
                    item.setBoxId(null);
                    item.setBoxNo(null);
                }
            });
            Box box = boxMapper.selectById(boxId);
            if (box != null) {
                box.setStatus("0");//设置为待使用
                boxMapper.updateById(box);
            }
        }
        putDtlMapper.updateBatchById(putDtls);


//        List<Box> boxList = ids.stream().map(id->{
//            Box box = boxMapper.selectById(id);
//            box.setStatus("0");
//            return box;
//        }).collect(Collectors.toList());
//
//        if(StringUtils.isNotEmpty(putTaskId)){
//            List<PutDtl> putDtls = putDtlMapper.selectList(new LambdaQueryWrapper<PutDtl>().eq(PutDtl::getTaskId,putTaskId));
//            if(putDtls != null && putDtls.size() > 0){
//                putDtls.forEach(item->{
//                    if(ids.contains(item.getBoxId())){
//                        item.setBoxId(null);
//                        item.setBoxNo(null);
//                    }
//                });
//               boolean flag =  putDtlMapper.insertOrUpdateBatch(putDtls);
//            }
//        }
//        boxMapper.updateBatchById(boxList)
        List<PutDtlVo> putDtlVos = putDtls.stream().map(item -> {
            PutDtlVo vo = new PutDtlVo();
            BeanUtil.copyProperties(item, vo);
            vo.setStoreName(storeMapper.selectVoById(vo.getStoreId()).getName());
            return vo;
        }).collect(Collectors.toList());
        return putDtlVos;
    }

    public String getNo() {

        LambdaQueryWrapper<PutTask> lqw = Wrappers.lambdaQuery();
        Long maxNumObject = baseMapper.selectCount(lqw);
        String num = "";
        String todayStr = DateUtils.date2String(new Date(), "yyMMdd");

        if (maxNumObject == null) {
            num = todayStr + "000001";
        } else {
            String maxnumStr = "00000" + maxNumObject.toString();
            String maxnumNo = maxnumStr.substring(maxnumStr.length() - 6, maxnumStr.length());
            String nextnumNo = StringUtils.nextNo(maxnumNo, 6);
            num = todayStr + nextnumNo;
        }
        return num;
    }

    //日志添加
    public void addOperatorLog(String objid, String type, String content) {

        OperatorLog log = new OperatorLog();
        log.setId(IdUtil.simpleUUID());
        log.setObjid(objid);
        log.setDelFlag("0");
        log.setLogTime(new Date());
        if (LoginHelper.checkLoginUser()) {
            log.setUserId(LoginHelper.getUserId());
            log.setOperator(LoginHelper.getNickname());
        } else {
            log.setOperator("--");
        }
        log.setLogType(type);
        log.setContent(content);
        logMapper.insert(log);
    }

    //财物日志添加
    private PropertyLog saveLog(PutDtl dtl, String objid, Long deptId, String storeId, String content, Long logDeptId, List<SysOss> osses) {

        PropertyLog propertyLog = new PropertyLog();

        BeanUtil.copyProperties(dtl, propertyLog, "id");
        propertyLog.setId(IdUtil.simpleUUID());
        propertyLog.setObjid(objid);
        propertyLog.setLogTime(new Date());
        propertyLog.setLogType(PropertyLogType.PUT_TASK.getCode());//0-移交登记 1-入库 2-出库 3-调用 4-处置 5-交接 6-上架 7-挑拣
        propertyLog.setContent(content);
        propertyLog.setReceiveDept(deptId);
        if (LoginHelper.checkLoginUser()) {
            propertyLog.setUserId(LoginHelper.getUserId());
            propertyLog.setOperator(LoginHelper.getNickname());
            SysDept dept = deptMapper.selectById(LoginHelper.getDeptId());
            propertyLog.setNode(PropertyLogNode.getNodeCodeByBuss(dept.getLevel(), "6"));
        } else {
            propertyLog.setOperator("--");
            propertyLog.setNode(PropertyLogNode.getNodeCodeByBuss(3l, "6"));
        }
        propertyLog.setInfo(JsonUtils.toJsonString(dtl));
        propertyLog.setDelFlag("0");

        propertyLog.setStoreId(storeId);

        propertyLogMapper.insert(propertyLog);

        if (osses != null && osses.size() > 0) {
            for (SysOss oss : osses) {
                SysOss copyOss = new SysOss();
                BeanUtil.copyProperties(oss, copyOss, "ossId");
                copyOss.setObjid(propertyLog.getId());
                copyOss.setBuss("propertyLog");
                sysOssMapper.insert(copyOss);
            }
        }

        return propertyLog;
    }


    @Override
    public Boolean syncUpdateBySmartCabinet(SmartCabinetInVo vo) {

        boolean flag = false;
        //处理数据
        if (vo != null && StringUtils.isNotBlank(vo.getProId())) {
            String[] proIds = vo.getProId().split(",");
            for (String id : proIds) {
                PutDtl dtl = putDtlMapper.selectById(id);
                if (dtl.getStatus().equals("1")) {
                    throw new ServiceException("ID:" + vo.getProId() + "财物已在柜，请勿重复操作");
                }
                PutTask update = baseMapper.selectById(dtl.getTaskId());
                //入柜状态
                dtl.setStatus("1");
                putDtlMapper.updateById(dtl);
                //生成库存
                InventoryBo inBo = new InventoryBo();
                inBo.setStoreId(dtl.getStoreId());
                inBo.setAreaId(dtl.getAreaId());
                inBo.setLocatorId(dtl.getLocatorId());
                inBo.setPno(dtl.getPno());
                inBo.setName(dtl.getName());
                inBo.setInnums(dtl.getNums());
                inBo.setNums(dtl.getNums());
                inBo.setDeptId(update.getDeptId());
                inBo.setPics(dtl.getPics());
                inBo.setDelFlag("0");
                inBo.setTaskId(update.getId());
                inBo.setMark("0");
                inBo.setBoxNo(dtl.getBoxNo());
                inBo.setPutTaskType("0");
                Property property = propertyMapper.selectOne(new LambdaQueryWrapper<Property>().eq(Property::getPno, dtl.getPno()));
                if (property != null) {
                    inBo.setQrcode(property.getQrcode());
                }
                if (isReturnTask(update.getWid())) {
                    inBo.setPutTaskType("1");
                }
                iInventoryService.addInventory(inBo);

                //生成仓库日志  0-入库；1-出库 2-处置 3-上架 4-挑拣 5-看样
                StoreLogBo logBo = new StoreLogBo();
                logBo.setDeptId(update.getDeptId());
                logBo.setStoreId(dtl.getStoreId());
                logBo.setLogTime(new Date());
                logBo.setUserId(update.getOperator());
                logBo.setOperator("智能柜反馈");
                logBo.setLogType("3");
                logBo.setDelFlag("0");
                logBo.setContent(JsonUtils.toJsonString(vo));
                iStoreLogService.insertByBo(logBo);

                //生成财物日志维护财物状态

                property.setBelongDeptId(update.getDeptId());
                property.setBelongStoreId(dtl.getStoreId());
                property.setLocatorId(dtl.getLocatorId());
                propertyMapper.updateById(property);

                PropertyLog propertyLog = saveLog(dtl, update.getId(), update.getDeptId(), dtl.getStoreId(), vo.getEntryType() == 0 ? "正常入柜" : "变更库位", update.getDeptId(), null);
//                propertyLogMapper.insert(propertyLog);
                PropertyLogModelsVo pushData = new PropertyLogModelsVo();
                pushData.setApi("proBase");
                pushData.setData(propertyLogMapper.selectPropertyLogVoByID(propertyLog.getId()));
                PushDatasUtil.pushPropertyDatas(pushData);
                //更新库位
                if (!StringUtils.isEmpty(vo.getSmartCabinetId())) {
                    CabinetGroup group = cabinetGroupMapper.selectOne(new LambdaQueryWrapper<CabinetGroup>().eq(CabinetGroup::getSnNumber, vo.getSmartCabinetId()));
                    if (group == null) {
                        return false;
                    }
                    Locator locator = locatorMapper.selectOne(new LambdaQueryWrapper<Locator>()
                            .eq(vo.getCabinetAisleRelaId() != null, Locator::getCabinetAisleRelaId, vo.getSmartCabinetId())
                            .eq(StringUtils.isNotBlank(vo.getSmartCabinetGrid()), Locator::getAisleCode, vo.getSmartCabinetGrid())
                            .eq(Locator::getCabinetGroupId, group.getId())
                    );
                    if (locator != null) {
                        //更新库位数量
                        locator.setPnums(locator.getPnums() == null ? 1 : locator.getPnums() + 1);

                        StoreArea storeArea = storeAreaMapper.selectOne(new LambdaQueryWrapper<StoreArea>().eq(StoreArea::getId,
                                group.getAreaId()));

                        int status;

                        if ("GZ".equals(storeArea.getAno())) {
                            //贵重物品智能柜放一个就设置满
                            status = 2;
                        } else {
                            if (vo.getIsFull() != null) {
                                //已满状态
                                status = vo.getIsFull() + 1;
                            } else {
                                //为满设置已使用状态
                                status = 1;
                            }
                        }

                        locator.setStatus(Integer.toString(status));
                        //更新柜号数量（+）
                        locatorMapper.updateById(locator);
                    }
                    group.setPnums(group.getPnums() == null ? 1 : group.getPnums() + 1);
                }

                Warehouse warehouse = warehouseMapper.selectById(update.getWid());
                //判断上架任务单的上架任务是否已完成
                Long unPuts = putDtlMapper.selectCount(new LambdaQueryWrapper<PutDtl>()
                        .eq(PutDtl::getTaskId, dtl.getTaskId())
                        .eq(PutDtl::getStatus, "0")
                );
                if (unPuts == null || unPuts == 0) {
                    update.setStatus("1");
                    update.setFinishTime(new Date(vo.getInSmartCabinetTime()));

                    warehouse.setIsFinish("1");

                    addOperatorLog(StringUtils.isNotEmpty(warehouse.getTaskId()) ? warehouse.getTaskId() : warehouse.getId(), "wms", "完成上架");
                }
                flag = baseMapper.updateById(update) > 0;
                if (flag) {
                    warehouseMapper.updateById(warehouse);
                }
//                WarehouseVo warehouseVo = warehouseMapper.selectWarehouseVoByID(update.getWid());
                addOperatorLog(StringUtils.isNotEmpty(warehouse.getTaskId()) ? warehouse.getTaskId() : warehouse.getId(), "wms", "上架");
            }
        }
        return flag;
    }

    public boolean isReturnTask(String wid) {

        if (!StringUtils.isEmpty(wid)) {
            Warehouse warehouse = warehouseMapper.selectById(wid);
            if (warehouse != null && !StringUtils.isEmpty(warehouse.getTaskId())) {
                Task task = taskMapper.selectById(warehouse.getTaskId());
                if (task != null && !StringUtils.isEmpty(task.getReturnId())) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public void pushPutTaskDatas(String id) {

        PutTaskVo taskVo = baseMapper.selectPutTaskVoByID(id);
        PutDtlBo putDtl = new PutDtlBo();
        putDtl.setTaskId(id);
        putDtl.setDelFlag("0");
        taskVo.setItems(putDtlMapper.selectPutDtlList(putDtl));
        PushDatasUtil.pushPutTaskDatas(taskVo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updatePutDtlByBoxNo(PutTaskBo bo) {

        final boolean[] flag = {false};
        if (bo.getItems() != null && bo.getItems().size() > 0) {
            bo.getItems().stream().forEach(item -> {
                PutDtl dtl = new PutDtl();
                BeanUtil.copyProperties(item, dtl);
                flag[0] = putDtlMapper.updateById(dtl) > 0;

                /**
                 * 是否已上架
                 */
                if (dtl.getStatus().equals("1")) {
                    InventoryVo inventoryVo = iInventoryService.queryByPno(dtl.getPno(), dtl.getStoreId(), null);
                    if (inventoryVo != null && StringUtils.isNotEmpty(inventoryVo.getId())) {
                        InventoryBo inventoryBo = new InventoryBo();
                        BeanUtil.copyProperties(inventoryVo, inventoryBo);
                        inventoryBo.setBoxNo(dtl.getBoxNo());
                        flag[0] = iInventoryService.updateByBo(inventoryBo);
                    }
                }

            });
        }

        return flag[0];
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean refreshPutTask(PutTaskBo bo) {

        PutTaskVo vo = baseMapper.queryPutTaskVoByWarehouseID(bo.getId());
        WarehouseVo warehouseVo = warehouseMapper.selectWarehouseVoByID(bo.getId());
        boolean flag = true;

        WarehouseDtlBo wDtlBo = new WarehouseDtlBo();
        wDtlBo.setWid(warehouseVo.getId());
        List<WarehouseDtlVo> wdtls = warehouseDtlMapper.selectWarehouseDtlList(wDtlBo);

        PutDtlBo dtlBo = new PutDtlBo();
        dtlBo.setTaskId(vo.getId());
        List<PutDtlVo> olds = putDtlMapper.selectPutDtlList(dtlBo);
        List<PutDtl> dtls = new ArrayList<>();

        if (wdtls != null && wdtls.size() > 0) {
            String[] ignoreProperties = new String[]{"id", "createBy", "createTime", "updateBy", "updateTime"};
            dtls = wdtls.stream().map(item -> {
                PutDtl dtl = putDtlMapper.selectOne(new LambdaQueryWrapper<PutDtl>().eq(PutDtl::getPno, item.getPno()).eq(PutDtl::getTaskId, vo.getId()));
                if (dtl == null) {
                    dtl = new PutDtl();
                    BeanUtil.copyProperties(item, dtl, ignoreProperties);
                    dtl.setId(IdUtil.simpleUUID());
                    dtl.setStatus("0");
                    dtl.setDelFlag("0");
                    dtl.setTaskId(vo.getId());
                }

                Iterator iterator = olds.iterator();
                while (iterator.hasNext()) {
                    PutDtlVo putDtl = (PutDtlVo) iterator.next();
                    if (putDtl.getId().equals(dtl.getId())) {
                        iterator.remove();
                    }
                }
                return dtl;
            }).collect(Collectors.toList());
            //计算财物数量
            Long nums = dtls.stream().mapToLong(item -> item.getNums()).sum();
            PutTask update = new PutTask();
            update.setNums(nums);
            baseMapper.update(update, new LambdaQueryWrapper<PutTask>().eq(PutTask::getId, vo.getId()));
        }
        if (dtls.size() > 0) {
            putDtlMapper.insertOrUpdateBatch(dtls);
        }
        if (olds != null && olds.size() > 0) {
            olds.forEach(item -> {
                putDtlMapper.deleteVoById(item.getId());
            });
        }


        return flag;
    }

}
